/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.unal.bioingenium.kbmed.retrieval.text.similarity;

import co.edu.unal.bioingenium.kbmed.features.CompactFeatureVector;

/**
 *
 * @author Alejandro Riveros Cruz
 */
public class Cosine {

    /**
     * 
     */
    public Cosine() {
    }

    /**
     *
     * @param x1 
     * @param x2 
     * @return 
     */
    public float getValue(float[] x1, float[] x2) {
        float cos, num, dem1, dem2;
        num = 0;
        dem1 = 0;
        dem2 = 0;
        for (int i = 0; i < x1.length; i++) {
            if (x1[i] > 0 && x2[i] > 0) {
                num = num + x1[i] * x2[i];
                dem1 = dem1 + (float) Math.pow(x1[i], 2);
                dem2 = dem2 + (float) Math.pow(x2[i], 2);
            } else {
                if (x1[i] > 0) {
                    dem1 = dem1 + (float) Math.pow(x1[i], 2);
                }
                if (x2[i] > 0) {
                    dem2 = dem2 + (float) Math.pow(x2[i], 2);
                }
            }
        }
        dem1 = (float) Math.sqrt(dem1);
        dem2 = (float) Math.sqrt(dem2);
        cos = num / (dem1 * dem2);
        if (Float.valueOf(cos).isNaN()) {
            return 0;
        }
        return cos;
    }

    /**
     *
     * @param x1 
     * @param x2 
     * @return 
     */
    public float getValue(CompactFeatureVector x1, CompactFeatureVector x2) {
        float cos, num, dem1, dem2;
        num = 0;
        dem1 = 0;
        dem2 = 0;
        CompactFeatureVector featureShort;
        if (x1.getFeaturesLength() < x2.getFeaturesLength()) {
            featureShort = x1;
        } else {
            featureShort = x2;
        }
        for (int indexKey : featureShort.getIndexKeys()) {
            num = num + x1.getValue(indexKey) * x2.getValue(indexKey);
        }
        for (int indexKey : x1.getIndexKeys()) {
            dem1 = dem1 + (float) Math.pow(x1.getValue(indexKey), 2);
        }
        dem1 = (float) Math.sqrt(dem1);
        for (int indexKey : x2.getIndexKeys()) {
            dem2 = dem2 + (float) Math.pow(x2.getValue(indexKey), 2);
        }
        dem2 = (float) Math.sqrt(dem2);
        cos = num / (dem1 * dem2);
        if (Float.valueOf(cos).isNaN()) {
            return 0;
        }
        return cos;
    }
}
